package service

import (
	"dta-apk/global"
	"dta-apk/huawei"
	"dta-apk/model"
	"dta-apk/oppo"
	"dta-apk/platapi"
	"dta-apk/query/request"
	"dta-apk/query/response"
	"dta-apk/utils"
	"dta-apk/vivo"
	"dta-apk/xiaomi"
	"fmt"
	"log"
	"strconv"
	"strings"
	"sync"
)

// 应用列表
func GetAppList() []response.AppListResult {
	var appList []response.AppListResult
	var apps []model.AppModel
	result := model.FindAll(&apps, nil)
	if result {
		for _, app := range apps {
			latestVersionStr := "未发布版本"
			latestVersion := getLatestVersionOfApp(app.ID)
			if latestVersion != nil {
				latestVersionStr = latestVersion.VersionCode
			}
			appInfo := response.AppListResult{
				AppId:         strconv.Itoa(int(app.ID)),
				PackageName:   app.PackageName,
				AppName:       app.AppName,
				PushTime:      app.PushTime,
				Status:        appStatus[app.Status],
				LatestVersion: latestVersionStr,
			}
			appList = append(appList, appInfo)
		}
	}
	return appList
}

// 查询应用最新版本
func getLatestVersionOfApp(appId uint) *model.VersionModel {
	var version model.VersionModel
	result := model.DbConn.Order("version_code DESC").Where("app_id = ?", appId).First(&version)
	if result.Error != nil || result.RowsAffected == 0 {
		return nil
	}
	return &version
}

// 创建应用
func CreateApp(appAddQuery request.AppAddQuery) (bool, string) {
	// 查询应用是否已经存在
	var appQuery model.AppModel
	result := model.DbConn.Where("app_name = ? OR package_name = ?", appAddQuery.AppName, appAddQuery.PackageName).Find(&appQuery)
	if result.RowsAffected != 0 {
		return false, "应用已存在"
	}

	// 新建模型
	app := model.AppModel{
		AppName:     appAddQuery.AppName,
		PackageName: appAddQuery.PackageName,
		Status:      1, // 应用状态正常
		PushTime:    utils.Now(),
	}
	// 创建
	result = model.DbConn.Create(&app)
	if result.Error != nil {
		fmt.Println(result.Error)
		return false, "创建失败"
	}
	// 保存要发布的平台
	plats := appAddQuery.Plats
	var appPlats []model.AppPlatModel
	for _, plat := range plats {
		appPlat := model.AppPlatModel{
			AppId: strconv.Itoa(int(app.ID)),
			Plat:  plat,
		}
		appPlats = append(appPlats, appPlat)

	}
	model.Save(&appPlats)
	return true, "创建成功"

}

// 更新应用
func UpdateApp(updateQuery request.AppUpdateQuery) (bool, string) {
	var app model.AppModel
	result := model.FindById(&app, updateQuery.AppId)
	if !result {
		return false, "应用不存在"
	}
	app.AppName = updateQuery.AppName
	// 更新应用数据
	model.DbConn.Save(&app)
	// 更新发布平台
	plats := updateQuery.Plats
	if len(plats) > 0 {
		// 先删除再保存
		model.DbConn.Delete(&model.AppPlatModel{}, "app_id = ?", updateQuery.AppId)
		// 保存要发布的平台
		var appPlats []model.AppPlatModel
		for _, plat := range plats {
			appPlat := model.AppPlatModel{
				AppId: strconv.Itoa(int(app.ID)),
				Plat:  plat,
			}
			appPlats = append(appPlats, appPlat)

		}
		model.Save(&appPlats)
	}
	return true, "保存成功"

}

// 删除应用
func DeleteApp(appId string) {
	id, _ := strconv.ParseUint(appId, 10, 64)
	model.DbConn.Delete(&model.AppModel{}, id)
}

// 查询应用
func GetApp(appId string) response.AppResult {
	var appResult response.AppResult
	var app model.AppModel
	result := model.FindById(&app, appId)
	if result {
		appResult.AppId = strconv.Itoa(int(app.ID))
		appResult.AppName = app.AppName
		appResult.PackageName = app.PackageName
	}
	// 查询发布平台
	var plats []string
	var appPlats []model.AppPlatModel
	model.FindAll(&appPlats, &model.AppPlatModel{AppId: appId})
	for _, appPlat := range appPlats {
		plats = append(plats, appPlat.Plat)
	}
	appResult.Plats = plats

	return appResult
}

// 保存更新应用资料
func UpdateAppInfo(appInfoQuery request.AppInfo) bool {
	// 图标文件上传到文件服务器
	iconFilePath, iconFileName, err := utils.SaveToLocalFile(*appInfoQuery.Icon)
	if err != nil {
		log.Println(err)
		return false
	}
	iconFileUrl := utils.PutFile(iconFileName, iconFilePath)
	// 保存的应用数据
	appInfo := model.AppInfoModel{
		AppId:      appInfoQuery.AppId,
		Icon:       iconFileUrl,
		Summary:    appInfoQuery.ShortDesc,
		Desc:       appInfoQuery.Desc,
		PrivacyUrl: appInfoQuery.PrivacyUrl,
		IcpNum:     appInfoQuery.Icp,
	}
	// 保存数据
	err = model.Save(&appInfo)
	if err != nil {
		fmt.Println(err)
		return false
	}
	// 保存发布平台
	plates := appInfoQuery.Plates
	if len(plates) > 0 {
		var appPlates []model.AppPlatModel
		for _, v := range plates {
			plate := model.AppPlatModel{
				AppId: appInfoQuery.AppId,
				Plat:  v,
			}
			appPlates = append(appPlates, plate)
		}
		model.Save(appPlates)
	}

	return true
}

// 获取应用各平台在线资料
func GetPlatAppInfo(appId string) map[string]interface{} {
	var platInfoMap = make(map[string]interface{})
	// 查询发布平台
	var appPlats []model.AppPlatModel
	result := model.FindAll(&appPlats, &model.AppPlatModel{AppId: appId})
	if !result {
		return platInfoMap
	}
	// 查询app信息
	var app model.AppModel
	result = model.FindById(&app, appId)
	if !result {
		return platInfoMap
	}
	// 遍历循环获取每个平台的应用信息
	for _, appPlat := range appPlats {
		platName := appPlat.Plat
		platApi := platapi.Plat{Plat: platName}
		platAppInfo := platApi.GetAppDetails(app.PackageName)
		platInfoMap[platName] = platAppInfo
	}
	return platInfoMap
}

// 获取应用同步后的资料
func GetAppInfoSync(appId string) response.AppInfoResult {
	var appInfoResult response.AppInfoResult
	// 查询发布平台
	var plats []string
	var appPlats []model.AppPlatModel
	model.FindAll(&appPlats, &model.AppPlatModel{AppId: appId})
	for _, appPlat := range appPlats {
		plats = append(plats, appPlat.Plat)
	}
	appInfoResult.Plats = plats
	// 查询信息
	var appInfo model.AppInfoModel
	result := model.FindOne(&appInfo, model.AppInfoModel{AppId: appId})
	if !result {
		return appInfoResult
	}
	// 查询应用截图
	var appScreenshots []model.FileModel
	var screenshots []string
	result = model.FindAll(&appScreenshots, &model.FileModel{Belong: appId, Type: "app_screenshot"})
	if result {
		for _, appScreenshot := range appScreenshots {
			screenshots = append(screenshots, appScreenshot.Path)
		}
	}

	// 转返回数据结构
	return response.AppInfoResult{
		AppId:      appId,
		Icon:       appInfo.Icon,
		ShortDesc:  appInfo.Summary,
		Desc:       appInfo.Desc,
		PrivacyUrl: appInfo.PrivacyUrl,
		Icp:        appInfo.IcpNum,
		Plats:      plats,
		Screenshot: screenshots,
	}
}

// 同步平台资料
func SyncAppInfo(appId string) bool {
	if appId == "" {
		return false
	}
	// 查询应用
	var app model.AppModel
	result := model.FindById(&app, appId)
	if !result {
		return false
	}
	// 查询应用平台信息
	var appPlates []model.AppPlatModel
	result = model.FindAll(&appPlates, &model.AppPlatModel{AppId: appId})
	if result {
		plate := appPlates[0]
		// 通过oppo平台获取，返回的信息比较全
		if plate.Plat == "oppo" {
			detail, result := oppo.GetAppDetails(app.PackageName, "")

			if result {
				// 查询是否存在
				var appInfo model.AppInfoModel
				result := model.DbConn.Find(&appInfo, &model.AppInfoModel{AppId: appId})
				appInfoModel := &model.AppInfoModel{
					AppId:      appId,
					Icon:       detail.IconUrl,
					Desc:       detail.DetailDesc,
					Summary:    detail.Summary,
					PrivacyUrl: detail.PrivacySourceUrl,
					IcpNum:     detail.IcpUrl,
				}
				if result.RowsAffected == 0 {
					model.Save(appInfoModel)
				} else {
					appInfoModel.ID = appInfo.ID
					model.Update(appInfoModel)
				}
				// 保存应用截图
				picUrlAll := detail.PicUrl
				picUrls := strings.Split(picUrlAll, ",")
				if len(picUrls) > 0 {
					model.DbConn.Where("belong = ? and type = ?", appId, "app_screenshot").Delete(&model.FileModel{})
					for _, picUrl := range picUrls {
						picFile := &model.FileModel{
							Name:   "",
							Path:   picUrl,
							Type:   "app_screenshot",
							Belong: appId,
							Md5:    "",
						}
						// 保存截图数据
						model.Save(picFile)
					}
				}

				return true
			}
		}

	}
	return false

}

// 提交审核应用资料
func CheckAppInfo(appId string, platforms []string) {
	// 查询app信息
	var app model.AppModel
	model.FindById(&app, appId)
	// 处理每个应用平台逻辑
	for _, pf := range platforms {
		// 小米应用市场
		if pf == "xiaomi" {
			xiaomi.GetAppDetails(app.PackageName, global.Config.App.XiaoMi.UserName)
		} else if pf == "oppo" {
			_, isResult := oppo.GetAppDetails(app.PackageName, "")
			if isResult {
				oppoUpdateInfo := oppo.OppoUpdateInfo{
					PkgName: app.PackageName,
				}
				oppo.UpdateAppInfo(oppoUpdateInfo)
			} else {
				fmt.Println("该app在oppo应用市场不存在，请先去往oppo开放平台创建应用")
			}
		}
	}
}

// 查询审核结果
func GetCheckInfo(appId string) []response.CheckInfo {
	var checkInfos []response.CheckInfo
	// 查询app信息
	var app model.AppModel
	result := model.FindById(&app, appId)
	if result {
		// TODO
		// 查询最新版本的审核情况
		var appPublishes []model.AppPublishModel
		result := model.DbConn.Select("*, MAX(version_code)").Group("plat").Find(&appPublishes, &model.AppPublishModel{AppId: appId}).Order("version_code DESC").Scan(&appPublishes)
		if result.Error != nil || result.RowsAffected == 0 {
			return checkInfos
		}
		// 获取最后的审核详情
		for _, publish := range appPublishes {
			var checkInfo response.CheckInfo
			checkInfo.CheckStatus = publish.CheckStatus
			checkInfo.CheckStatusDesc = publish.CheckDesc
			checkInfo.PushStatus = strconv.Itoa(publish.PublishStatus)
			checkInfo.PushStatusDesc = publish.PublishDesc
			checkInfo.PushType = publish.PublishType
			checkInfo.VersionCode = publish.VersionCode
			checkInfo.Plat = publish.Plat
			checkInfos = append(checkInfos, checkInfo)
		}

	}
	return checkInfos
}

// 提交应用审核
func PublishApp(query request.AppPublishQuery) bool {
	updateResult := true
	// 查询app信息
	var app model.AppModel
	result := model.FindById(&app, query.AppId)
	if !result {
		return false
	}

	// 查询版本信息
	var version model.VersionModel
	result = model.FindById(&version, query.PublishVersion)
	if !result {
		return false
	}
	// 查询apk文件
	var apkFile model.FileModel
	result = model.FindOne(&apkFile, &model.FileModel{Belong: query.PublishVersion})
	if !result {
		utils.LogError(utils.ErrorLog{Message: "apk文件不存在"})
		return false
	}
	// 下载apk文件到本地
	apkFilePath, result := utils.DownloadToLocalFile(apkFile.Path, "apk")
	if !result {
		utils.LogError(utils.ErrorLog{Message: "apk文件下载失败"})
		return false
	}
	// 版本说明
	updateDesc := version.Remark
	plates := query.PublishPlate
	if len(plates) == 0 {
		return false
	}
	appId := query.AppId
	versionId := query.PublishVersion
	// 启动线程处理发布逻辑
	go func() {
		var wg sync.WaitGroup
		for _, plate := range plates {
			if plate == platapi.Xiaomi {
				wg.Add(1)
				go publishToPlate(appId, versionId, platapi.Xiaomi, func() (bool, string) {
					return xiaomi.UpdateApk(app.PackageName, app.AppName, updateDesc, apkFilePath)
				}, &wg)
			} else if plate == platapi.Vivo {
				wg.Add(1)
				go publishToPlate(appId, versionId, platapi.Vivo, func() (bool, string) {
					return vivo.UpdateApk(app.PackageName, apkFilePath, updateDesc, version.VersionCode)
				}, &wg)
			} else if plate == platapi.Huawei {
				// 提交审核
				wg.Add(1)
				go publishToPlate(appId, versionId, platapi.Huawei, func() (bool, string) {
					return huawei.UpdateApk(app.PackageName, apkFilePath, updateDesc)
				}, &wg)
			} else if plate == platapi.Oppo {
				wg.Add(1)
				go publishToPlate(appId, versionId, platapi.Oppo, func() (bool, string) {
					return oppo.UpdateApk(app.PackageName, apkFilePath, version.VersionCode, updateDesc, query.PublishType)
				}, &wg)
			}
		}
		// 等待所有推送完成
		wg.Wait()
		// 删除临时文件
		utils.DeleteFile(apkFilePath)
		// 发布审核完成后，修改当前版本的状态为已发布
		version.Status = VersionPublished
		model.Update(&version)
		// 启动定时器，获取审核结果
		StartAppCheckInfoTicker(query.AppId, query.PublishVersion, app.PackageName)
	}()
	return updateResult
}

// 应用发布各平台逻辑
func publishToPlate(appId, versionId, plate string, publishApp func() (bool, string), wg *sync.WaitGroup) response.PublishResult {
	var result response.PublishResult
	defer wg.Done()
	// 查询是否已经提交审核
	isPlate, platePublish := getVersionPublishOfPlate(versionId, plate)
	if isPlate {
		// 如果存在已发布版本并且状态不是发布失败，就不需要发布
		if platePublish.PublishStatus != 7 {
			result.Success = true
			result.Msg = versionStatus[platePublish.PublishStatus]
			return result
		}
	}
	// 对应平台审核
	publishResult, publishMsg := publishApp()
	// 初始发布状态
	platePublishStatus := 1 // 成功
	if !publishResult {
		platePublishStatus = 2 // 失败
	}
	result.Success = publishResult
	result.Msg = publishMsg
	// 保存发布信息
	saveVersionPublishToPlate(appId, versionId, plate, platePublishStatus, publishMsg)
	return result
}

// 查询版本在平台发布的详情
func getVersionPublishOfPlate(versionId string, plate string) (bool, model.AppPublishModel) {
	// 查询是否已经提交审核
	var versionPublish model.AppPublishModel
	isExist := model.FindOne(&versionPublish, &model.AppPublishModel{VersionId: versionId, Plat: plate})
	return isExist, versionPublish
}

// 保存版本在各平台审核发布的结果
func saveVersionPublishToPlate(appId, versionId, plate string, status int, desc string) {
	versionPublish := model.AppPublishModel{
		AppId:         appId,
		VersionId:     versionId,
		PublishType:   "1",
		Plat:          plate,
		PublishStatus: status,
		PublishDesc:   desc,
		PublishTime:   utils.Now(),
		CheckStatus:   "3",
	}
	model.Save(&versionPublish)
}

// 同步应用在各平台的审核详情
func SyncCheckInfo(appId string) bool {
	// 查询app信息
	var app model.AppModel
	result := model.FindById(&app, appId)
	if !result {
		return false
	}
	// 查询app对应的发布平台
	var plates []model.AppPlatModel
	platResult := model.DbConn.Find(&plates, &model.AppPlatModel{AppId: appId})
	if platResult.RowsAffected == 0 || platResult.Error != nil {
		log.Println("查询应用发布平台失败")
		return false
	}
	// 遍历各个平台，查询版本在平台发布的详情
	for _, plate := range plates {
		// 查询app审核结果
		publishResult := GetCheckInfoOfPlate(app.PackageName, plate.Plat)
		var publish model.AppPublishModel
		// 查询该应用是否存在审核数据，如果不存在就保存
		findResult := model.DbConn.Find(&publish, &model.AppPublishModel{AppId: appId, VersionCode: publishResult.VersionCode, Plat: plate.Plat})
		if findResult.Error != nil {
			return false
		}
		// 如果不存在就保存新数据
		if findResult.RowsAffected == 0 {
			versionPublish := model.AppPublishModel{
				AppId:         appId,
				VersionCode:   publishResult.VersionCode,
				PublishType:   "2",
				Plat:          plate.Plat,
				PublishStatus: 1,
				PublishDesc:   "",
				PublishTime:   "",
				CheckStatus:   publishResult.CheckStatus,
				CheckDesc:     publishResult.CheckDesc,
			}
			model.Save(&versionPublish)
		} else {
			// 更新审核结果
			publish.CheckDesc = publishResult.CheckDesc
			publish.CheckStatus = publishResult.CheckStatus
			publish.VersionCode = publishResult.VersionCode
			model.Update(&publish)
		}

	}
	return true
}
